library(tidyverse)
library(caret)

Data

Numbers divided by quartiles in order to determine the profiles of rankings that are slow and fast. The profiles are divided in four equal parts considering the number of alternatives and one quarter is taking as fast and the other considered as slow.

Storing counts in `nn`, as `n` already present in input
ℹ Use `name = "new_name"` to pick a new name.
Using alpha for a discrete variable is not advised.
# For the reggresion problem
# fitControl <- trainControl(
#   method = "repeatedcv",
#   number = 5,
#   repeats = 2)

fitControl <- trainControl(
  method = "repeatedcv",
  number = 5,
  repeats = 2,
  classProbs = TRUE,
  summaryFunction = prSummary)

Predicting execution time for profiles of a fixed size

Joining, by = c("n", "m", "id")
# Fit control para 
fitControl <- trainControl(
  method = "repeatedcv",
  number = 5,
  repeats = 2,
  classProbs = TRUE,
  summaryFunction = prSummary)

Training 25%-75%

# Da muy malos resultados porque está desbalanceado
# # Para n = 10
# totrain <- data_quartiles %>% 
#   filter(n==10) %>% 
#   mutate(quartile = fct_collapse(quartile, fast = c("q1"), slow = c("q2","q3","q4"))) %>%
#   select(starts_with("mu"), quartile) 
# set.seed(123)
# trainIndex <- createDataPartition(totrain$quartile, p = .8, 
#                                   list = FALSE, 
#                                   times = 1)
# dataTrain <- totrain[ trainIndex,]
# dataTest  <- totrain[-trainIndex,]
# set.seed(123)
# mclas_rf_10 <- train(
#   quartile ~., data = dataTrain, 
#   method = "rf",
#   tuneLength = 3,
#   trControl = fitControl,
#   metric = "AUC"
# )
# mclas_rf_10
library(ROSE)

Para n = 10 con los datos normalizados

Y en test:

pred <- predict(rf_10_rose_norm, dataTest)
postResample(pred = pred, obs = dataTest$quartile)
confusionMatrix(data = pred, reference = dataTest$quartile, mode = "prec_recall")

Y sin normalizar:

fitControl <- trainControl(
  method = "repeatedcv",
  number = 5,
  repeats = 2,
  classProbs = TRUE,
  summaryFunction = prSummary,
  sampling = "up")
Error in trainControl(method = "repeatedcv", number = 5, repeats = 2,  : 
  no se pudo encontrar la función "trainControl"
rf_10_rose
Random Forest 

2240 samples
  16 predictor
   2 classes: 'fast', 'slow' 

No pre-processing
Resampling: Cross-Validated (5 fold, repeated 2 times) 
Summary of sample sizes: 1792, 1792, 1792, 1792, 1792, 1792, ... 
Resampling results across tuning parameters:

  mtry  AUC        Precision  Recall     F        
   2    0.7875077  0.7439379  0.7243243  0.7336813
   9    0.7803522  0.7403700  0.7391892  0.7394959
  16    0.7768513  0.7310205  0.7436937  0.7371480

AUC was used to select the optimal model using the largest value.
The final value used for the model was mtry = 2.
confusionMatrix(data = pred, reference = (dataTest %>% filter(quartile == "fast"))$quartile, mode = "prec_recall")
Confusion Matrix and Statistics

          Reference
Prediction fast slow
      fast  125    0
      slow   15    0
                                          
               Accuracy : 0.8929          
                 95% CI : (0.8294, 0.9388)
    No Information Rate : 1               
    P-Value [Acc > NIR] : 1.0000000       
                                          
                  Kappa : 0               
                                          
 Mcnemar's Test P-Value : 0.0003006       
                                          
              Precision : 1.0000          
                 Recall : 0.8929          
                     F1 : 0.9434          
             Prevalence : 1.0000          
         Detection Rate : 0.8929          
   Detection Prevalence : 0.8929          
      Balanced Accuracy :     NA          
                                          
       'Positive' Class : fast            
                                          
rose_train <- ROSE(quartile ~ ., data  = totrain)$data %>%
  mutate(quartile = fct_relevel(quartile, "slow", after = Inf))
Error in ROSE(quartile ~ ., data = totrain) : 
  no se pudo encontrar la función "ROSE"

Comparación de las variables más importantes

(vip_mreg_rf_8_norm + vip_mreg_rf_9_norm + vip_mreg_rf_10_norm) |
(vip_mreg_rf_8 + vip_mreg_rf_9 + vip_mreg_rf_10)
totrain <- data_quartiles %>% 
  mutate(quartile = fct_collapse(quartile, fast = c("q1"), slow = c("q2","q3","q4"))) %>%
  select(starts_with("mu"), quartile) %>%
  filter(n!=10)
totest <- data_quartiles %>% 
  mutate(quartile = fct_collapse(quartile, fast = c("q1"), slow = c("q2","q3","q4"))) %>%
  select(starts_with("mu"), quartile) %>%
  filter(n==10)

set.seed(123)
rose_train <- ROSE(quartile ~ ., data  = totrain)$data %>%
  mutate(quartile = fct_relevel(quartile, "slow", after = Inf))
print(table(rose_train$quartile))

fast slow 
4146 4254 
set.seed(123)
trainIndex <- createDataPartition(rose_train$quartile, p = .8, 
                                  list = FALSE, 
                                  times = 1)
dataTrain <- rose_train[ trainIndex,]
dataTest  <- rose_train[-trainIndex,]

Seeking for the outliers

data_outliers_normalized <- left_join(data_normalized %>% 
                               mutate(id = as.double(as.character(id))), outliers) 
Joining, by = c("n", "m", "id")
fitControl <- trainControl(
  method = "repeatedcv",
  number = 10,
  repeats = 5,
  classProbs = TRUE,
  summaryFunction = twoClassSummary,
  sampling = "down")

data_outliers_normalized
totrain <- data_outliers_normalized %>% 
  filter(n==8) %>%
  select(starts_with("mu"), outlier)
  
set.seed(123)
trainIndex <- createDataPartition(totrain$outlier, p = .8, 
                                  list = FALSE, 
                                  times = 1)

dataTrain <- totrain[ trainIndex,]
dataTest  <- totrain[-trainIndex,]

set.seed(123)
rf_8_outlier <- train(
  outlier ~., data = dataTrain, method = "rf",
  tuneLength = 10,
  trControl = fitControl,
  metric = "ROC"
)

vip_rf_8_outlier <- vip(rf_8_outlier)
pred <- predict(rf_8_outlier, dataTest)
confusionMatrix(data = pred, reference = dataTest$outlier, mode = "sens_spec")
Confusion Matrix and Statistics

          Reference
Prediction yes  no
       yes  27 109
       no    9 415
                                          
               Accuracy : 0.7893          
                 95% CI : (0.7531, 0.8224)
    No Information Rate : 0.9357          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.2363          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.75000         
            Specificity : 0.79198         
         Pos Pred Value : 0.19853         
         Neg Pred Value : 0.97877         
             Prevalence : 0.06429         
         Detection Rate : 0.04821         
   Detection Prevalence : 0.24286         
      Balanced Accuracy : 0.77099         
                                          
       'Positive' Class : yes             
                                          
sens_rf_8_outlier <- sensitivity(pred, dataTest$outlier)
pred <- predict(rf_8_outlier, dataTest, type= "prob")
auc_rf_8_outlier <- AUC(pred$yes, ifelse(dataTest$outlier == "yes", 1, 0))
totrain <- data_outliers_normalized %>% 
  filter(n==9) %>%
  select(starts_with("mu"), outlier)
  
set.seed(123)
trainIndex <- createDataPartition(totrain$outlier, p = .8, 
                                  list = FALSE, 
                                  times = 1)

dataTrain <- totrain[ trainIndex,]
dataTest  <- totrain[-trainIndex,]

set.seed(123)
rf_9_outlier <- train(
  outlier ~., data = dataTrain, method = "rf",
  tuneLength = 10,
  trControl = fitControl,
  metric = "ROC"
)

vip_rf_9_outlier <- vip(rf_9_outlier)
pred <- predict(rf_9_outlier, dataTest)
confusionMatrix(data = pred, reference = dataTest$outlier, mode = "sens_spec")
Confusion Matrix and Statistics

          Reference
Prediction yes  no
       yes  35  99
       no    9 416
                                          
               Accuracy : 0.8068          
                 95% CI : (0.7716, 0.8387)
    No Information Rate : 0.9213          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.3117          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.79545         
            Specificity : 0.80777         
         Pos Pred Value : 0.26119         
         Neg Pred Value : 0.97882         
             Prevalence : 0.07871         
         Detection Rate : 0.06261         
   Detection Prevalence : 0.23971         
      Balanced Accuracy : 0.80161         
                                          
       'Positive' Class : yes             
                                          
sens_rf_9_outlier <- sensitivity(pred, dataTest$outlier)
pred <- predict(rf_9_outlier, dataTest, type= "prob")
auc_rf_9_outlier <- AUC(pred$yes, ifelse(dataTest$outlier == "yes", 1, 0))
totrain <- data_outliers_normalized %>% 
  filter(n==10) %>%
  select(starts_with("mu"), outlier)
  
set.seed(123)
trainIndex <- createDataPartition(totrain$outlier, p = .8, 
                                  list = FALSE, 
                                  times = 1)

dataTrain <- totrain[ trainIndex,]
dataTest  <- totrain[-trainIndex,]

set.seed(123)
rf_10_outlier <- train(
  outlier ~., data = dataTrain, method = "rf",
  tuneLength = 10,
  trControl = fitControl,
  metric = "ROC"
)

vip_rf_10_outlier <- vip(rf_10_outlier)
pred <- predict(rf_10_outlier, dataTest)
confusionMatrix(data = pred, reference = dataTest$outlier, mode = "sens_spec")
Confusion Matrix and Statistics

          Reference
Prediction yes  no
       yes  34 139
       no    7 379
                                          
               Accuracy : 0.7388          
                 95% CI : (0.7003, 0.7748)
    No Information Rate : 0.9267          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.226           
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.82927         
            Specificity : 0.73166         
         Pos Pred Value : 0.19653         
         Neg Pred Value : 0.98187         
             Prevalence : 0.07335         
         Detection Rate : 0.06082         
   Detection Prevalence : 0.30948         
      Balanced Accuracy : 0.78046         
                                          
       'Positive' Class : yes             
                                          
sens_rf_10_outlier <- sensitivity(pred, dataTest$outlier)
pred <- predict(rf_10_outlier, dataTest, type= "prob")
auc_rf_10_outlier <- AUC(pred$yes, ifelse(dataTest$outlier == "yes", 1, 0))
vip_rf_8_outlier + vip_rf_9_outlier + vip_rf_10_outlier

totrain <- data_outliers_normalized %>% 
  select(starts_with("mu"), outlier)
  
set.seed(123)
trainIndex <- createDataPartition(totrain$outlier, p = .8, 
                                  list = FALSE, 
                                  times = 1)

dataTrain <- totrain[ trainIndex,]
dataTest  <- totrain[-trainIndex,]

set.seed(123)
rf_all_outlier <- train(
  #outlier ~., data = dataTrain, method = "rf",
  outlier ~., data = dataTrain, method = "rf",
  tuneLength = 8,
  trControl = fitControl,
  metric = "ROC"
)

pred <- predict(rf_all_outlier, dataTest)
postResample(pred = pred, obs = dataTest$outlier)
 Accuracy     Kappa 
0.7641453 0.2541812 
confusionMatrix(data = pred, reference = dataTest$outlier, mode = "sens_spec")
Confusion Matrix and Statistics

          Reference
Prediction  yes   no
       yes  102  377
       no    19 1181
                                          
               Accuracy : 0.7641          
                 95% CI : (0.7431, 0.7843)
    No Information Rate : 0.9279          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.2542          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.84298         
            Specificity : 0.75802         
         Pos Pred Value : 0.21294         
         Neg Pred Value : 0.98417         
             Prevalence : 0.07207         
         Detection Rate : 0.06075         
   Detection Prevalence : 0.28529         
      Balanced Accuracy : 0.80050         
                                          
       'Positive' Class : yes             
                                          
sens_rf_all_outlier <- sensitivity(pred, dataTest$outlier)

vip(rf_all_outlier)


pred <- predict(rf_all_outlier, dataTest, type= "prob")
auc_rf_all_outlier <- AUC(pred$yes, ifelse(dataTest$outlier == "yes", 1, 0))
vip(rf_all_outlier, 
    horizontal = FALSE,
    aesthetics = list(width = .5)) +
  theme_bw() + 
  scale_x_discrete(labels = function(x) parse(text=paste0("mu[", str_remove(x, "mu"), "]"))) +
  ylab("Variable\nimportance") +
  theme(text=element_text(size = 12, family="Times New Roman"),
        axis.title.x = element_text(margin = margin(t = 10)))
  
sens_rf_8_outlier
[1] 0.75
auc_rf_8_outlier
[1] 0.8313454
sens_rf_9_outlier
[1] 0.7954545
auc_rf_9_outlier
[1] 0.8796778
sens_rf_10_outlier
[1] 0.8292683
auc_rf_10_outlier
[1] 0.8204869
sens_rf_all_outlier
[1] 0.8429752
auc_rf_all_outlier
[1] 0.863586
confusionMatrix(data = pred, reference = totest$outlier, mode = "sens_spec")
Confusion Matrix and Statistics

          Reference
Prediction  yes   no
       yes  169  811
       no    38 1782
                                          
               Accuracy : 0.6968          
                 95% CI : (0.6794, 0.7138)
    No Information Rate : 0.9261          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.1853          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.81643         
            Specificity : 0.68723         
         Pos Pred Value : 0.17245         
         Neg Pred Value : 0.97912         
             Prevalence : 0.07393         
         Detection Rate : 0.06036         
   Detection Prevalence : 0.35000         
      Balanced Accuracy : 0.75183         
                                          
       'Positive' Class : yes             
                                          

Ahora para los cuartiles

totrain <- data_quartiles_normalized %>% 
  filter(n!=10) %>%
  select(starts_with("mu"), quartile) %>%
  mutate(quartile = fct_collapse(quartile, fast = c("q1"), slow = c("q2","q3","q4")))

totest <- data_quartiles_normalized %>% 
  filter(n==10) %>%
  select(starts_with("mu"), quartile) %>%
  mutate(quartile = fct_collapse(quartile, fast = c("q1"), slow = c("q2","q3","q4")))
  
set.seed(123)
trainIndex <- createDataPartition(totrain$quartile, p = .8, 
                                  list = FALSE, 
                                  times = 1)

dataTrain <- totrain[ trainIndex,]
dataTest  <- totrain[-trainIndex,]

set.seed(123)
rf_quartiles <- train(
  quartile ~., data = dataTrain, method = "rf",
  tuneLength = 10,
  trControl = fitControl,
  metric = "ROC"
) 

pred <- predict(rf_quartiles, dataTest)
postResample(pred = pred, obs = dataTest$quartile)
 Accuracy     Kappa 
0.6839286 0.3257143 
# confusionMatrix(data = pred, reference = dataTest$quartile, mode = "sens_spec")
pred <- predict(rf_quartiles, totest)
postResample(pred = pred, obs = totest$quartile)
 Accuracy     Kappa 
0.6967857 0.3713439 
confusionMatrix(data = pred, reference = totest$quartile, mode = "sens_spec")
Confusion Matrix and Statistics

          Reference
Prediction fast slow
      fast  576  725
      slow  124 1375
                                          
               Accuracy : 0.6968          
                 95% CI : (0.6794, 0.7138)
    No Information Rate : 0.75            
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.3713          
                                          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.8229          
            Specificity : 0.6548          
         Pos Pred Value : 0.4427          
         Neg Pred Value : 0.9173          
             Prevalence : 0.2500          
         Detection Rate : 0.2057          
   Detection Prevalence : 0.4646          
      Balanced Accuracy : 0.7388          
                                          
       'Positive' Class : fast            
                                          
pred <- predict(rf_quartiles, totest, type= "prob")
AUC(pred$fast, ifelse(totest$quartile == "fast", 1, 0))
[1] 0.8010837
vip(rf_quartiles)

LS0tCnRpdGxlOiAiVHJhaW5pbmciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjYXJldCkKYGBgCgojIERhdGEKCmBgYHtyIGVjaG89RkFMU0V9CmdncGxvdCh0aW1lcywgYWVzKHg9YXMubnVtZXJpYyhtKSx5PWV4ZWNfdGltZSxjb2xvcj1xdWFydGlsZSxncm91cD1tKSkgKyAKICBnZW9tX2ppdHRlcihoZWlnaHQgPSAwKSArCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IG1lYW4oZXhlY190aW1lKSkpICsKICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gbWVkaWFuKGV4ZWNfdGltZSkpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgZmFjZXRfd3JhcCh+biwgc2NhbGVzID0gImZyZWVfeCIpICsKICBjb29yZF9mbGlwKCkgKwogIHhsYWIoIiIpICsgeWxhYigiIikgKwogIHRoZW1lX2xpZ2h0KCkKYGBgCgpgYGB7cn0KZ2dwbG90KHRpbWVzLCBhZXMoZXhlY190aW1lKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF93cmFwKG5+Liwgc2NhbGVzID0gImZyZWVfeCIsIG5yb3cgPSAzLCBzdHJpcC5wb3NpdGlvbiA9ICJyaWdodCIpICArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG4uYnJlYWtzID0gMTApICsKICB4bGFiKCIiKSArIHlsYWIoIiIpICsKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCk51bWJlcnMgZGl2aWRlZCBieSBxdWFydGlsZXMgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIHRoZSBwcm9maWxlcyBvZiByYW5raW5ncyB0aGF0IGFyZSBzbG93IGFuZCBmYXN0LiBUaGUgcHJvZmlsZXMgYXJlIGRpdmlkZWQgaW4gZm91ciBlcXVhbCBwYXJ0cyBjb25zaWRlcmluZyB0aGUgbnVtYmVyIG9mIGFsdGVybmF0aXZlcyBhbmQgb25lIHF1YXJ0ZXIgaXMgdGFraW5nIGFzIGZhc3QgYW5kIHRoZSBvdGhlciBjb25zaWRlcmVkIGFzIHNsb3cuCgpgYGB7ciBlY2hvPUZBTFNFfQpnZ3Bsb3QodGltZXMgJT4lIGNvdW50KG4sbSxxdWFydGlsZSksIGFlcyhtLG5uLGZpbGw9cXVhcnRpbGUpKSArCiAgZ2VvbV9iYXIoYWVzKGFscGhhID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIobSkpJSUyPT0wKSxzdGF0PSJpZGVudGl0eSIsIHBvc2l0aW9uPSJmaWxsIikgKwogIGdlb21fdGV4dChhZXMobGFiZWw9bm4pLHBvc2l0aW9uID0gcG9zaXRpb25fZmlsbCh2anVzdCA9IDAuNSksIGFuZ2xlID0gOTApICsKICBmYWNldF9ncmlkKC5+bikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC43NSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC41KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjI1KSArCiAgc2NhbGVfYWxwaGFfZGlzY3JldGUocmFuZ2UgPSBjKDAuNiwxKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCmBgYHtyfQojIEZvciB0aGUgcmVnZ3Jlc2lvbiBwcm9ibGVtCiMgZml0Q29udHJvbCA8LSB0cmFpbkNvbnRyb2woCiMgICBtZXRob2QgPSAicmVwZWF0ZWRjdiIsCiMgICBudW1iZXIgPSA1LAojICAgcmVwZWF0cyA9IDIpCgpmaXRDb250cm9sIDwtIHRyYWluQ29udHJvbCgKICBtZXRob2QgPSAicmVwZWF0ZWRjdiIsCiAgbnVtYmVyID0gNSwKICByZXBlYXRzID0gMiwKICBjbGFzc1Byb2JzID0gVFJVRSwKICBzdW1tYXJ5RnVuY3Rpb24gPSBwclN1bW1hcnkpCmBgYAoKIyBQcmVkaWN0aW5nIGV4ZWN1dGlvbiB0aW1lIGZvciBwcm9maWxlcyBvZiBhIGZpeGVkIHNpemUKCmBgYHtyfQpkYXRhX3F1YXJ0aWxlcyA8LSBsZWZ0X2pvaW4ocHJlZGljdF90aW1lcyAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShpZCA9IGFzLmRvdWJsZShhcy5jaGFyYWN0ZXIoaWQpKSksIHRpbWVzKSAKZGF0YV9xdWFydGlsZXMKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQpkYXRhX3F1YXJ0aWxlc19ub3JtYWxpemVkIDwtIGxlZnRfam9pbihkYXRhX25vcm1hbGl6ZWQgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGlkID0gYXMuZG91YmxlKGFzLmNoYXJhY3RlcihpZCkpKSwgdGltZXMpIApkYXRhX3F1YXJ0aWxlc19ub3JtYWxpemVkCmBgYAoKYGBge3J9CiMgRml0IGNvbnRyb2wgcGFyYSAKZml0Q29udHJvbCA8LSB0cmFpbkNvbnRyb2woCiAgbWV0aG9kID0gInJlcGVhdGVkY3YiLAogIG51bWJlciA9IDUsCiAgcmVwZWF0cyA9IDIsCiAgY2xhc3NQcm9icyA9IFRSVUUsCiAgc3VtbWFyeUZ1bmN0aW9uID0gcHJTdW1tYXJ5KQpgYGAKClRyYWluaW5nIDI1JS03NSUKCmBgYHtyfQojIERhIG11eSBtYWxvcyByZXN1bHRhZG9zIHBvcnF1ZSBlc3TDoSBkZXNiYWxhbmNlYWRvCiMgIyBQYXJhIG4gPSAxMAojIHRvdHJhaW4gPC0gZGF0YV9xdWFydGlsZXMgJT4lIAojICAgZmlsdGVyKG49PTEwKSAlPiUgCiMgICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfY29sbGFwc2UocXVhcnRpbGUsIGZhc3QgPSBjKCJxMSIpLCBzbG93ID0gYygicTIiLCJxMyIsInE0IikpKSAlPiUKIyAgIHNlbGVjdChzdGFydHNfd2l0aCgibXUiKSwgcXVhcnRpbGUpIAojIHNldC5zZWVkKDEyMykKIyB0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24odG90cmFpbiRxdWFydGlsZSwgcCA9IC44LCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCA9IEZBTFNFLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSAxKQojIGRhdGFUcmFpbiA8LSB0b3RyYWluWyB0cmFpbkluZGV4LF0KIyBkYXRhVGVzdCAgPC0gdG90cmFpblstdHJhaW5JbmRleCxdCiMgc2V0LnNlZWQoMTIzKQojIG1jbGFzX3JmXzEwIDwtIHRyYWluKAojICAgcXVhcnRpbGUgfi4sIGRhdGEgPSBkYXRhVHJhaW4sIAojICAgbWV0aG9kID0gInJmIiwKIyAgIHR1bmVMZW5ndGggPSAzLAojICAgdHJDb250cm9sID0gZml0Q29udHJvbCwKIyAgIG1ldHJpYyA9ICJBVUMiCiMgKQojIG1jbGFzX3JmXzEwCmBgYAoKYGBge3J9CmxpYnJhcnkoUk9TRSkKYGBgCgpQYXJhIG4gPSAxMCBjb24gbG9zIGRhdG9zIG5vcm1hbGl6YWRvcwoKYGBge3J9CnRvdHJhaW4gPC0gZGF0YV9xdWFydGlsZXNfbm9ybWFsaXplZCAlPiUgCiAgZmlsdGVyKG49PTEwKSAlPiUKICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfY29sbGFwc2UocXVhcnRpbGUsIGZhc3QgPSBjKCJxMSIpLCBzbG93ID0gYygicTIiLCJxMyIsInE0IikpKSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIHF1YXJ0aWxlKQogIApzZXQuc2VlZCgxMjMpIApyb3NlX3RyYWluIDwtIFJPU0UocXVhcnRpbGUgfiAuLCBkYXRhICA9IHRvdHJhaW4pJGRhdGEgJT4lCiAgbXV0YXRlKHF1YXJ0aWxlID0gZmN0X3JlbGV2ZWwocXVhcnRpbGUsICJzbG93IiwgYWZ0ZXIgPSBJbmYpKQojIHByaW50KHRhYmxlKHJvc2VfdHJhaW4kcXVhcnRpbGUpKQoKc2V0LnNlZWQoMTIzKQp0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24ocm9zZV90cmFpbiRxdWFydGlsZSwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCmRhdGFUcmFpbiA8LSByb3NlX3RyYWluWyB0cmFpbkluZGV4LF0KZGF0YVRlc3QgIDwtIHJvc2VfdHJhaW5bLXRyYWluSW5kZXgsXQoKc2V0LnNlZWQoMTIzKQpyZl8xMF9yb3NlX25vcm0gPC0gdHJhaW4oCiAgcXVhcnRpbGUgfi4sIGRhdGEgPSBkYXRhVHJhaW4sIG1ldGhvZCA9ICJyZiIsCiAgdHVuZUxlbmd0aCA9IDMsCiAgdHJDb250cm9sID0gZml0Q29udHJvbCwKICBtZXRyaWMgPSAiQVVDIgopCgp2aXBfcmZfMTBfcm9zZV9ub3JtIDwtIHZpcChyZl8xMF9yb3NlX25vcm0pCmNvbmZ1c2lvbk1hdHJpeChyZl8xMF9yb3NlX25vcm0pCmBgYAoKClkgZW4gdGVzdDoKCmBgYHtyfQpwcmVkIDwtIHByZWRpY3QocmZfMTBfcm9zZV9ub3JtLCBkYXRhVGVzdCkKcG9zdFJlc2FtcGxlKHByZWQgPSBwcmVkLCBvYnMgPSBkYXRhVGVzdCRxdWFydGlsZSkKY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkLCByZWZlcmVuY2UgPSBkYXRhVGVzdCRxdWFydGlsZSwgbW9kZSA9ICJwcmVjX3JlY2FsbCIpCmBgYAoKWSBzaW4gbm9ybWFsaXphcjoKCmBgYHtyfQpmaXRDb250cm9sIDwtIHRyYWluQ29udHJvbCgKICBtZXRob2QgPSAicmVwZWF0ZWRjdiIsCiAgbnVtYmVyID0gNSwKICByZXBlYXRzID0gMiwKICBjbGFzc1Byb2JzID0gVFJVRSwKICBzdW1tYXJ5RnVuY3Rpb24gPSBwclN1bW1hcnksCiAgc2FtcGxpbmcgPSAidXAiKQoKZGF0YV9xdWFydGlsZXMgPC0gbGVmdF9qb2luKHByZWRpY3RfdGltZXMgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoaWQgPSBhcy5kb3VibGUoaWQpKSwgdGltZXMpIAoKdG90cmFpbiA8LSBkYXRhX3F1YXJ0aWxlcyAlPiUgCiAgZmlsdGVyKG49PTEwKSAlPiUKICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfY29sbGFwc2UocXVhcnRpbGUsIGZhc3QgPSBjKCJxMSIpLCBzbG93ID0gYygicTIiLCJxMyIsInE0IikpKSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIHF1YXJ0aWxlKQogIAp0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24odG90cmFpbiRxdWFydGlsZSwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCgpkYXRhVHJhaW4gPC0gdG90cmFpblsgdHJhaW5JbmRleCxdCmRhdGFUZXN0ICA8LSB0b3RyYWluWy10cmFpbkluZGV4LF0KCnJmXzEwX3Jvc2UgPC0gdHJhaW4oCiAgcXVhcnRpbGUgfi4sIGRhdGEgPSBkYXRhVHJhaW4sIG1ldGhvZCA9ICJyZiIsCiAgdHVuZUxlbmd0aCA9IDMsCiAgdHJDb250cm9sID0gZml0Q29udHJvbCwKICBtZXRyaWMgPSAiQVVDIgopCnJmXzEwX3Jvc2UKYGBgCgoKCgpgYGB7cn0KZGF0YV9xdWFydGlsZXMgPC0gbGVmdF9qb2luKHByZWRpY3RfdGltZXMgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoaWQgPSBhcy5kb3VibGUoaWQpKSwgdGltZXMpIAoKdG90cmFpbiA8LSBkYXRhX3F1YXJ0aWxlcyAlPiUgCiAgZmlsdGVyKG49PTEwKSAlPiUKICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfY29sbGFwc2UocXVhcnRpbGUsIGZhc3QgPSBjKCJxMSIpLCBzbG93ID0gYygicTIiLCJxMyIsInE0IikpKSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIHF1YXJ0aWxlKQogIAp0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24odG90cmFpbiRxdWFydGlsZSwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCgpkYXRhVHJhaW4gPC0gdG90cmFpblsgdHJhaW5JbmRleCxdCmRhdGFUZXN0ICA8LSB0b3RyYWluWy10cmFpbkluZGV4LF0KCnNldC5zZWVkKDEyMykgCnJvc2VfdHJhaW4gPC0gUk9TRShxdWFydGlsZSB+IC4sIGRhdGEgID0gZGF0YVRyYWluKSRkYXRhICU+JQogIG11dGF0ZShxdWFydGlsZSA9IGZjdF9yZWxldmVsKHF1YXJ0aWxlLCAic2xvdyIsIGFmdGVyID0gSW5mKSkKCgpzZXQuc2VlZCgxMjMpCnJmXzEwX3Jvc2UgPC0gdHJhaW4oCiAgcXVhcnRpbGUgfi4sIGRhdGEgPSByb3NlX3RyYWluLCBtZXRob2QgPSAicmYiLAogIHR1bmVMZW5ndGggPSAzLAogIHRyQ29udHJvbCA9IGZpdENvbnRyb2wsCiAgbWV0cmljID0gIkFVQyIKKQoKdmlwX3JmXzEwX3Jvc2UgPC0gdmlwKHJmXzEwX3Jvc2UpCmNvbmZ1c2lvbk1hdHJpeChyZl8xMF9yb3NlKQpgYGAKCmBgYHtyfQpwcmVkIDwtIHByZWRpY3QocmZfMTBfcm9zZSwgZGF0YVRlc3QpCnBvc3RSZXNhbXBsZShwcmVkID0gcHJlZCwgb2JzID0gZGF0YVRlc3QkcXVhcnRpbGUpCmNvbmZ1c2lvbk1hdHJpeChkYXRhID0gcHJlZCwgcmVmZXJlbmNlID0gZGF0YVRlc3QkcXVhcnRpbGUsIG1vZGUgPSAicHJlY19yZWNhbGwiKQpgYGAKCgoKCgoKYGBge3J9CmRhdGFfcXVhcnRpbGVzIDwtIGxlZnRfam9pbihwcmVkaWN0X3RpbWVzICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKGlkID0gYXMuZG91YmxlKGlkKSksIHRpbWVzKSAKCnRvdHJhaW4gPC0gZGF0YV9xdWFydGlsZXMgJT4lIAogIGZpbHRlcihuPT0xMCkgJT4lCiAgbXV0YXRlKHF1YXJ0aWxlID0gZmN0X2NvbGxhcHNlKHF1YXJ0aWxlLCBmYXN0ID0gYygicTEiKSwgc2xvdyA9IGMoInEyIiwicTMiLCJxNCIpKSkgJT4lCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJtdSIpLCBxdWFydGlsZSkKICAKc2V0LnNlZWQoMTIzKSAKcm9zZV90cmFpbiA8LSBST1NFKHF1YXJ0aWxlIH4gLiwgZGF0YSAgPSB0b3RyYWluKSRkYXRhICU+JQogIG11dGF0ZShxdWFydGlsZSA9IGZjdF9yZWxldmVsKHF1YXJ0aWxlLCAic2xvdyIsIGFmdGVyID0gSW5mKSkKIyBwcmludCh0YWJsZShyb3NlX3RyYWluJHF1YXJ0aWxlKSkKCnNldC5zZWVkKDEyMykKdHJhaW5JbmRleCA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKHJvc2VfdHJhaW4kcXVhcnRpbGUsIHAgPSAuOCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSAxKQpkYXRhVHJhaW4gPC0gcm9zZV90cmFpblsgdHJhaW5JbmRleCxdCmRhdGFUZXN0ICA8LSByb3NlX3RyYWluWy10cmFpbkluZGV4LF0KCnNldC5zZWVkKDEyMykKcmZfMTBfcm9zZSA8LSB0cmFpbigKICBxdWFydGlsZSB+LiwgZGF0YSA9IGRhdGFUcmFpbiwgbWV0aG9kID0gInJmIiwKICB0dW5lTGVuZ3RoID0gMywKICB0ckNvbnRyb2wgPSBmaXRDb250cm9sLAogIG1ldHJpYyA9ICJBVUMiCikKCnZpcF9yZl8xMF9yb3NlIDwtIHZpcChyZl8xMF9yb3NlKQpjb25mdXNpb25NYXRyaXgocmZfMTBfcm9zZSkKYGBgCgpgYGB7cn0Kc2V0LnNlZWQoMTIzKQpycGFydF8xMF9yb3NlX25vcm0gPC0gdHJhaW4oCiAgcXVhcnRpbGUgfi4sIGRhdGEgPSBkYXRhVHJhaW4sIG1ldGhvZCA9ICJubmV0IiwKICB0dW5lTGVuZ3RoID0gMywKICB0ckNvbnRyb2wgPSBmaXRDb250cm9sLAogIHByZVByb2Nlc3MgPSBjKCJjZW50ZXIiLCJzY2FsZSIpLAogIG1ldHJpYyA9ICJBVUMiCikKYGBgCgoKCgpDb21wYXJhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBtw6FzIGltcG9ydGFudGVzCgpgYGB7cn0KKHZpcF9tcmVnX3JmXzhfbm9ybSArIHZpcF9tcmVnX3JmXzlfbm9ybSArIHZpcF9tcmVnX3JmXzEwX25vcm0pIHwKKHZpcF9tcmVnX3JmXzggKyB2aXBfbXJlZ19yZl85ICsgdmlwX21yZWdfcmZfMTApCmBgYAoKCgoKCgoKCgoKYGBge3J9CnRvdHJhaW4gPC0gZGF0YV9xdWFydGlsZXMgJT4lIAogIG11dGF0ZShxdWFydGlsZSA9IGZjdF9jb2xsYXBzZShxdWFydGlsZSwgZmFzdCA9IGMoInExIiksIHNsb3cgPSBjKCJxMiIsInEzIiwicTQiKSkpICU+JQogIHNlbGVjdChzdGFydHNfd2l0aCgibXUiKSwgcXVhcnRpbGUpICU+JQogIGZpbHRlcihuIT0xMCkKdG90ZXN0IDwtIGRhdGFfcXVhcnRpbGVzICU+JSAKICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfY29sbGFwc2UocXVhcnRpbGUsIGZhc3QgPSBjKCJxMSIpLCBzbG93ID0gYygicTIiLCJxMyIsInE0IikpKSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIHF1YXJ0aWxlKSAlPiUKICBmaWx0ZXIobj09MTApCgpzZXQuc2VlZCgxMjMpCnJvc2VfdHJhaW4gPC0gUk9TRShxdWFydGlsZSB+IC4sIGRhdGEgID0gdG90cmFpbikkZGF0YSAlPiUKICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfcmVsZXZlbChxdWFydGlsZSwgInNsb3ciLCBhZnRlciA9IEluZikpCnByaW50KHRhYmxlKHJvc2VfdHJhaW4kcXVhcnRpbGUpKQoKc2V0LnNlZWQoMTIzKQp0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24ocm9zZV90cmFpbiRxdWFydGlsZSwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCmRhdGFUcmFpbiA8LSByb3NlX3RyYWluWyB0cmFpbkluZGV4LF0KZGF0YVRlc3QgIDwtIHJvc2VfdHJhaW5bLXRyYWluSW5kZXgsXQpgYGAKCgojIFNlZWtpbmcgZm9yIHRoZSBvdXRsaWVycwoKYGBge3J9CmRhdGFfb3V0bGllcnNfbm9ybWFsaXplZCA8LSBsZWZ0X2pvaW4oZGF0YV9ub3JtYWxpemVkICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShpZCA9IGFzLmRvdWJsZShhcy5jaGFyYWN0ZXIoaWQpKSksIG91dGxpZXJzKSAKCmZpdENvbnRyb2wgPC0gdHJhaW5Db250cm9sKAogIG1ldGhvZCA9ICJyZXBlYXRlZGN2IiwKICBudW1iZXIgPSAxMCwKICByZXBlYXRzID0gNSwKICBjbGFzc1Byb2JzID0gVFJVRSwKICBzdW1tYXJ5RnVuY3Rpb24gPSB0d29DbGFzc1N1bW1hcnksCiAgc2FtcGxpbmcgPSAiZG93biIpCgpkYXRhX291dGxpZXJzX25vcm1hbGl6ZWQKYGBgCgpgYGB7cn0KdG90cmFpbiA8LSBkYXRhX291dGxpZXJzX25vcm1hbGl6ZWQgJT4lIAogIGZpbHRlcihuPT04KSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIG91dGxpZXIpCiAgCnNldC5zZWVkKDEyMykKdHJhaW5JbmRleCA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKHRvdHJhaW4kb3V0bGllciwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCgpkYXRhVHJhaW4gPC0gdG90cmFpblsgdHJhaW5JbmRleCxdCmRhdGFUZXN0ICA8LSB0b3RyYWluWy10cmFpbkluZGV4LF0KCnNldC5zZWVkKDEyMykKcmZfOF9vdXRsaWVyIDwtIHRyYWluKAogIG91dGxpZXIgfi4sIGRhdGEgPSBkYXRhVHJhaW4sIG1ldGhvZCA9ICJyZiIsCiAgdHVuZUxlbmd0aCA9IDEwLAogIHRyQ29udHJvbCA9IGZpdENvbnRyb2wsCiAgbWV0cmljID0gIlJPQyIKKQoKdmlwX3JmXzhfb3V0bGllciA8LSB2aXAocmZfOF9vdXRsaWVyKQpwcmVkIDwtIHByZWRpY3QocmZfOF9vdXRsaWVyLCBkYXRhVGVzdCkKY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkLCByZWZlcmVuY2UgPSBkYXRhVGVzdCRvdXRsaWVyLCBtb2RlID0gInNlbnNfc3BlYyIpCnNlbnNfcmZfOF9vdXRsaWVyIDwtIHNlbnNpdGl2aXR5KHByZWQsIGRhdGFUZXN0JG91dGxpZXIpCnByZWQgPC0gcHJlZGljdChyZl84X291dGxpZXIsIGRhdGFUZXN0LCB0eXBlPSAicHJvYiIpCmF1Y19yZl84X291dGxpZXIgPC0gQVVDKHByZWQkeWVzLCBpZmVsc2UoZGF0YVRlc3Qkb3V0bGllciA9PSAieWVzIiwgMSwgMCkpCmBgYAoKYGBge3J9CnRvdHJhaW4gPC0gZGF0YV9vdXRsaWVyc19ub3JtYWxpemVkICU+JSAKICBmaWx0ZXIobj09OSkgJT4lCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJtdSIpLCBvdXRsaWVyKQogIApzZXQuc2VlZCgxMjMpCnRyYWluSW5kZXggPC0gY3JlYXRlRGF0YVBhcnRpdGlvbih0b3RyYWluJG91dGxpZXIsIHAgPSAuOCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSAxKQoKZGF0YVRyYWluIDwtIHRvdHJhaW5bIHRyYWluSW5kZXgsXQpkYXRhVGVzdCAgPC0gdG90cmFpblstdHJhaW5JbmRleCxdCgpzZXQuc2VlZCgxMjMpCnJmXzlfb3V0bGllciA8LSB0cmFpbigKICBvdXRsaWVyIH4uLCBkYXRhID0gZGF0YVRyYWluLCBtZXRob2QgPSAicmYiLAogIHR1bmVMZW5ndGggPSAxMCwKICB0ckNvbnRyb2wgPSBmaXRDb250cm9sLAogIG1ldHJpYyA9ICJST0MiCikKCnZpcF9yZl85X291dGxpZXIgPC0gdmlwKHJmXzlfb3V0bGllcikKcHJlZCA8LSBwcmVkaWN0KHJmXzlfb3V0bGllciwgZGF0YVRlc3QpCmNvbmZ1c2lvbk1hdHJpeChkYXRhID0gcHJlZCwgcmVmZXJlbmNlID0gZGF0YVRlc3Qkb3V0bGllciwgbW9kZSA9ICJzZW5zX3NwZWMiKQpzZW5zX3JmXzlfb3V0bGllciA8LSBzZW5zaXRpdml0eShwcmVkLCBkYXRhVGVzdCRvdXRsaWVyKQpwcmVkIDwtIHByZWRpY3QocmZfOV9vdXRsaWVyLCBkYXRhVGVzdCwgdHlwZT0gInByb2IiKQphdWNfcmZfOV9vdXRsaWVyIDwtIEFVQyhwcmVkJHllcywgaWZlbHNlKGRhdGFUZXN0JG91dGxpZXIgPT0gInllcyIsIDEsIDApKQpgYGAKCmBgYHtyfQp0b3RyYWluIDwtIGRhdGFfb3V0bGllcnNfbm9ybWFsaXplZCAlPiUgCiAgZmlsdGVyKG49PTEwKSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIG91dGxpZXIpCiAgCnNldC5zZWVkKDEyMykKdHJhaW5JbmRleCA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKHRvdHJhaW4kb3V0bGllciwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCgpkYXRhVHJhaW4gPC0gdG90cmFpblsgdHJhaW5JbmRleCxdCmRhdGFUZXN0ICA8LSB0b3RyYWluWy10cmFpbkluZGV4LF0KCnNldC5zZWVkKDEyMykKcmZfMTBfb3V0bGllciA8LSB0cmFpbigKICBvdXRsaWVyIH4uLCBkYXRhID0gZGF0YVRyYWluLCBtZXRob2QgPSAicmYiLAogIHR1bmVMZW5ndGggPSAxMCwKICB0ckNvbnRyb2wgPSBmaXRDb250cm9sLAogIG1ldHJpYyA9ICJST0MiCikKCnZpcF9yZl8xMF9vdXRsaWVyIDwtIHZpcChyZl8xMF9vdXRsaWVyKQpwcmVkIDwtIHByZWRpY3QocmZfMTBfb3V0bGllciwgZGF0YVRlc3QpCmNvbmZ1c2lvbk1hdHJpeChkYXRhID0gcHJlZCwgcmVmZXJlbmNlID0gZGF0YVRlc3Qkb3V0bGllciwgbW9kZSA9ICJzZW5zX3NwZWMiKQpzZW5zX3JmXzEwX291dGxpZXIgPC0gc2Vuc2l0aXZpdHkocHJlZCwgZGF0YVRlc3Qkb3V0bGllcikKcHJlZCA8LSBwcmVkaWN0KHJmXzEwX291dGxpZXIsIGRhdGFUZXN0LCB0eXBlPSAicHJvYiIpCmF1Y19yZl8xMF9vdXRsaWVyIDwtIEFVQyhwcmVkJHllcywgaWZlbHNlKGRhdGFUZXN0JG91dGxpZXIgPT0gInllcyIsIDEsIDApKQpgYGAKCmBgYHtyfQp2aXBfcmZfOF9vdXRsaWVyICsgdmlwX3JmXzlfb3V0bGllciArIHZpcF9yZl8xMF9vdXRsaWVyCmBgYAoKCmBgYHtyfQp0b3RyYWluIDwtIGRhdGFfb3V0bGllcnNfbm9ybWFsaXplZCAlPiUgCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJtdSIpLCBvdXRsaWVyKQogIApzZXQuc2VlZCgxMjMpCnRyYWluSW5kZXggPC0gY3JlYXRlRGF0YVBhcnRpdGlvbih0b3RyYWluJG91dGxpZXIsIHAgPSAuOCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSAxKQoKZGF0YVRyYWluIDwtIHRvdHJhaW5bIHRyYWluSW5kZXgsXQpkYXRhVGVzdCAgPC0gdG90cmFpblstdHJhaW5JbmRleCxdCgpzZXQuc2VlZCgxMjMpCnJmX2FsbF9vdXRsaWVyIDwtIHRyYWluKAogICNvdXRsaWVyIH4uLCBkYXRhID0gZGF0YVRyYWluLCBtZXRob2QgPSAicmYiLAogIG91dGxpZXIgfi4sIGRhdGEgPSBkYXRhVHJhaW4sIG1ldGhvZCA9ICJyZiIsCiAgdHVuZUxlbmd0aCA9IDgsCiAgdHJDb250cm9sID0gZml0Q29udHJvbCwKICBtZXRyaWMgPSAiUk9DIgopCgpwcmVkIDwtIHByZWRpY3QocmZfYWxsX291dGxpZXIsIGRhdGFUZXN0KQpwb3N0UmVzYW1wbGUocHJlZCA9IHByZWQsIG9icyA9IGRhdGFUZXN0JG91dGxpZXIpCmNvbmZ1c2lvbk1hdHJpeChkYXRhID0gcHJlZCwgcmVmZXJlbmNlID0gZGF0YVRlc3Qkb3V0bGllciwgbW9kZSA9ICJzZW5zX3NwZWMiKQpzZW5zX3JmX2FsbF9vdXRsaWVyIDwtIHNlbnNpdGl2aXR5KHByZWQsIGRhdGFUZXN0JG91dGxpZXIpCgp2aXAocmZfYWxsX291dGxpZXIpCgpwcmVkIDwtIHByZWRpY3QocmZfYWxsX291dGxpZXIsIGRhdGFUZXN0LCB0eXBlPSAicHJvYiIpCmF1Y19yZl9hbGxfb3V0bGllciA8LSBBVUMocHJlZCR5ZXMsIGlmZWxzZShkYXRhVGVzdCRvdXRsaWVyID09ICJ5ZXMiLCAxLCAwKSkKYGBgCgpgYGB7cn0KdmlwKHJmX2FsbF9vdXRsaWVyLCAKICAgIGhvcml6b250YWwgPSBGQUxTRSwKICAgIGFlc3RoZXRpY3MgPSBsaXN0KHdpZHRoID0gLjUpKSArCiAgdGhlbWVfYncoKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgcGFyc2UodGV4dD1wYXN0ZTAoIm11WyIsIHN0cl9yZW1vdmUoeCwgIm11IiksICJdIikpKSArCiAgeWxhYigiVmFyaWFibGVcbmltcG9ydGFuY2UiKSArCiAgdGhlbWUodGV4dD1lbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYW1pbHk9IlRpbWVzIE5ldyBSb21hbiIpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDEwKSkpCiAgCmBgYAoKCmBgYHtyfQpzZW5zX3JmXzhfb3V0bGllcgphdWNfcmZfOF9vdXRsaWVyCnNlbnNfcmZfOV9vdXRsaWVyCmF1Y19yZl85X291dGxpZXIKc2Vuc19yZl8xMF9vdXRsaWVyCmF1Y19yZl8xMF9vdXRsaWVyCnNlbnNfcmZfYWxsX291dGxpZXIKYXVjX3JmX2FsbF9vdXRsaWVyCmBgYAoKCmBgYHtyfQojIGZpdENvbnRyb2wgPC0gdHJhaW5Db250cm9sKAojICAgbWV0aG9kID0gInJlcGVhdGVkY3YiLAojICAgbnVtYmVyID0gMywKIyAgIHJlcGVhdHMgPSA1LAojICAgY2xhc3NQcm9icyA9IFRSVUUsCiMgICBzdW1tYXJ5RnVuY3Rpb24gPSB0d29DbGFzc1N1bW1hcnksCiMgICBzYW1wbGluZyA9ICJkb3duIikKCnRvdHJhaW4gPC0gZGF0YV9vdXRsaWVyc19ub3JtYWxpemVkICU+JSAKICBmaWx0ZXIobiE9MTApICU+JQogIHNlbGVjdChzdGFydHNfd2l0aCgibXUiKSwgb3V0bGllcikKCnRvdGVzdCA8LSBkYXRhX291dGxpZXJzX25vcm1hbGl6ZWQgJT4lIAogIGZpbHRlcihuPT0xMCkgJT4lCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJtdSIpLCBvdXRsaWVyKSAKICAKc2V0LnNlZWQoMTIzKQp0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24odG90cmFpbiRvdXRsaWVyLCBwID0gLjgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzID0gMSkKCmRhdGFUcmFpbiA8LSB0b3RyYWluWyB0cmFpbkluZGV4LF0KZGF0YVRlc3QgIDwtIHRvdHJhaW5bLXRyYWluSW5kZXgsXQoKc2V0LnNlZWQoMTIzKQpyZl9hbGxfb3V0bGllcjIgPC0gdHJhaW4oCiAgb3V0bGllciB+LiwgZGF0YSA9IGRhdGFUcmFpbiwgbWV0aG9kID0gInJmIiwgIyA4NSB3aXRoIHJwYXJ0MgogIHR1bmVMZW5ndGggPSA4LAogIHRyQ29udHJvbCA9IGZpdENvbnRyb2wsCiAgbWV0cmljID0gIlJPQyIKKQoKcHJlZCA8LSBwcmVkaWN0KHJmX2FsbF9vdXRsaWVyMiwgZGF0YVRlc3QpCnBvc3RSZXNhbXBsZShwcmVkID0gcHJlZCwgb2JzID0gZGF0YVRlc3Qkb3V0bGllcikKY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkLCByZWZlcmVuY2UgPSBkYXRhVGVzdCRvdXRsaWVyLCBtb2RlID0gInNlbnNfc3BlYyIpCnByZWQgPC0gcHJlZGljdChyZl9hbGxfb3V0bGllcjIsIHRvdGVzdCkKcG9zdFJlc2FtcGxlKHByZWQgPSBwcmVkLCBvYnMgPSB0b3Rlc3Qkb3V0bGllcikKY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkLCByZWZlcmVuY2UgPSB0b3Rlc3Qkb3V0bGllciwgbW9kZSA9ICJzZW5zX3NwZWMiKQoKCnByZWQgPC0gcHJlZGljdChyZl9hbGxfb3V0bGllcjIsIHRvdGVzdCwgdHlwZT0gInByb2IiKQpBVUMocHJlZCR5ZXMsIGlmZWxzZSh0b3Rlc3Qkb3V0bGllciA9PSAieWVzIiwgMSwgMCkpCgp2aXAocmZfYWxsX291dGxpZXIyKQpgYGAKCgojIEFob3JhIHBhcmEgbG9zIGN1YXJ0aWxlcwoKCmBgYHtyfQp0b3RyYWluIDwtIGRhdGFfcXVhcnRpbGVzX25vcm1hbGl6ZWQgJT4lIAogIGZpbHRlcihuIT0xMCkgJT4lCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJtdSIpLCBxdWFydGlsZSkgJT4lCiAgbXV0YXRlKHF1YXJ0aWxlID0gZmN0X2NvbGxhcHNlKHF1YXJ0aWxlLCBmYXN0ID0gYygicTEiKSwgc2xvdyA9IGMoInEyIiwicTMiLCJxNCIpKSkKCnRvdGVzdCA8LSBkYXRhX3F1YXJ0aWxlc19ub3JtYWxpemVkICU+JSAKICBmaWx0ZXIobj09MTApICU+JQogIHNlbGVjdChzdGFydHNfd2l0aCgibXUiKSwgcXVhcnRpbGUpICU+JQogIG11dGF0ZShxdWFydGlsZSA9IGZjdF9jb2xsYXBzZShxdWFydGlsZSwgZmFzdCA9IGMoInExIiksIHNsb3cgPSBjKCJxMiIsInEzIiwicTQiKSkpCiAgCnNldC5zZWVkKDEyMykKdHJhaW5JbmRleCA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKHRvdHJhaW4kcXVhcnRpbGUsIHAgPSAuOCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZXMgPSAxKQoKZGF0YVRyYWluIDwtIHRvdHJhaW5bIHRyYWluSW5kZXgsXQpkYXRhVGVzdCAgPC0gdG90cmFpblstdHJhaW5JbmRleCxdCgpzZXQuc2VlZCgxMjMpCnJmX3F1YXJ0aWxlcyA8LSB0cmFpbigKICBxdWFydGlsZSB+LiwgZGF0YSA9IGRhdGFUcmFpbiwgbWV0aG9kID0gInJmIiwKICB0dW5lTGVuZ3RoID0gMTAsCiAgdHJDb250cm9sID0gZml0Q29udHJvbCwKICBtZXRyaWMgPSAiUk9DIgopIAoKcHJlZCA8LSBwcmVkaWN0KHJmX3F1YXJ0aWxlcywgZGF0YVRlc3QpCnBvc3RSZXNhbXBsZShwcmVkID0gcHJlZCwgb2JzID0gZGF0YVRlc3QkcXVhcnRpbGUpCiMgY29uZnVzaW9uTWF0cml4KGRhdGEgPSBwcmVkLCByZWZlcmVuY2UgPSBkYXRhVGVzdCRxdWFydGlsZSwgbW9kZSA9ICJzZW5zX3NwZWMiKQpwcmVkIDwtIHByZWRpY3QocmZfcXVhcnRpbGVzLCB0b3Rlc3QpCnBvc3RSZXNhbXBsZShwcmVkID0gcHJlZCwgb2JzID0gdG90ZXN0JHF1YXJ0aWxlKQpjb25mdXNpb25NYXRyaXgoZGF0YSA9IHByZWQsIHJlZmVyZW5jZSA9IHRvdGVzdCRxdWFydGlsZSwgbW9kZSA9ICJzZW5zX3NwZWMiKQoKcHJlZCA8LSBwcmVkaWN0KHJmX3F1YXJ0aWxlcywgdG90ZXN0LCB0eXBlPSAicHJvYiIpCkFVQyhwcmVkJGZhc3QsIGlmZWxzZSh0b3Rlc3QkcXVhcnRpbGUgPT0gImZhc3QiLCAxLCAwKSkKCnZpcChyZl9xdWFydGlsZXMpCmBgYAoKYGBge3J9CnRvdHJhaW4gPC0gZGF0YV9xdWFydGlsZXNfbm9ybWFsaXplZCAlPiUgCiAgZmlsdGVyKG4hPTEwKSAlPiUKICBzZWxlY3Qoc3RhcnRzX3dpdGgoIm11IiksIHF1YXJ0aWxlKSAlPiUKICBtdXRhdGUocXVhcnRpbGUgPSBmY3RfY29sbGFwc2UocXVhcnRpbGUsIGZhc3QgPSBjKCJxMSIpLCBzbG93ID0gYygicTIiLCJxMyIsInE0IikpKQoKdG90ZXN0IDwtIGRhdGFfcXVhcnRpbGVzX25vcm1hbGl6ZWQgJT4lIAogIGZpbHRlcihuPT0xMCkgJT4lCiAgc2VsZWN0KHN0YXJ0c193aXRoKCJtdSIpLCBxdWFydGlsZSkgJT4lCiAgbXV0YXRlKHF1YXJ0aWxlID0gZmN0X2NvbGxhcHNlKHF1YXJ0aWxlLCBmYXN0ID0gYygicTEiKSwgc2xvdyA9IGMoInEyIiwicTMiLCJxNCIpKSkKICAKc2V0LnNlZWQoMTIzKQp0cmFpbkluZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24odG90cmFpbiRxdWFydGlsZSwgcCA9IC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lcyA9IDEpCgpkYXRhVHJhaW4gPC0gdG90cmFpblsgdHJhaW5JbmRleCxdCmRhdGFUZXN0ICA8LSB0b3RyYWluWy10cmFpbkluZGV4LF0KCnNldC5zZWVkKDEyMykKcmZfcXVhcnRpbGVzMiA8LSB0cmFpbigKICBxdWFydGlsZSB+LiwgZGF0YSA9IGRhdGFUcmFpbiwgbWV0aG9kID0gInJwYXJ0MiIsCiAgdHVuZUxlbmd0aCA9IDEwLAogIHRyQ29udHJvbCA9IGZpdENvbnRyb2wsCiAgbWV0cmljID0gIlJPQyIKKSAKCnByZWQgPC0gcHJlZGljdChyZl9xdWFydGlsZXMyLCBkYXRhVGVzdCkKcG9zdFJlc2FtcGxlKHByZWQgPSBwcmVkLCBvYnMgPSBkYXRhVGVzdCRxdWFydGlsZSkKIyBjb25mdXNpb25NYXRyaXgoZGF0YSA9IHByZWQsIHJlZmVyZW5jZSA9IGRhdGFUZXN0JHF1YXJ0aWxlLCBtb2RlID0gInNlbnNfc3BlYyIpCnByZWQgPC0gcHJlZGljdChyZl9xdWFydGlsZXMyLCB0b3Rlc3QpCnBvc3RSZXNhbXBsZShwcmVkID0gcHJlZCwgb2JzID0gdG90ZXN0JHF1YXJ0aWxlKQpjb25mdXNpb25NYXRyaXgoZGF0YSA9IHByZWQsIHJlZmVyZW5jZSA9IHRvdGVzdCRxdWFydGlsZSwgbW9kZSA9ICJzZW5zX3NwZWMiKQoKcHJlZCA8LSBwcmVkaWN0KHJmX3F1YXJ0aWxlczIsIHRvdGVzdCwgdHlwZT0gInByb2IiKQpBVUMocHJlZCRmYXN0LCBpZmVsc2UodG90ZXN0JHF1YXJ0aWxlID09ICJmYXN0IiwgMSwgMCkpCgp2aXAocmZfcXVhcnRpbGVzMikKYGBgCgpgYGB7cn0KdmlwKHJmX3F1YXJ0aWxlczIsIAogICAgbnVtX2ZlYXR1cmVzID0gNSwKICAgIGFlc3RoZXRpY3MgPSBsaXN0KHdpZHRoID0gLjUpKSArCiAgdGhlbWVfYncoKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgcGFyc2UodGV4dD1wYXN0ZTAoIm11WyIsIHN0cl9yZW1vdmUoeCwgIm11IiksICJdIikpKSArCiAgeWxhYigiVmFyaWFibGUgaW1wb3J0YW5jZSIpICsKICB0aGVtZSh0ZXh0PWVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhbWlseT0iVGltZXMgTmV3IFJvbWFuIiksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KG1hcmdpbiA9IG1hcmdpbih0ID0gMTApKSkKYGBgCgo=